package com.appspot.abcensys.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.Set;
import java.util.TreeMap;

import com.appspot.abcensys.shared.Afwezigheid;
import com.appspot.abcensys.shared.Gebruiker;
import com.appspot.abcensys.shared.Les;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;

/**
 * Afwezigheid Inzien
 * 
 * @author Hugo Zonderland
 */
public class AfwezigheidInzien {

	// AbcensysService
	private AbcensysServiceAsync service = (AbcensysServiceAsync) GWT.create(AbcensysService.class);
	
	// FlexTalbe
	private FlexTable flxTableHeader, flxTable;
	
	// Row counter
	int row;

	// Logger
	private static final Logger log = Logger.getLogger(AfwezigheidInzien.class.getName());
	
	/**
	 * Constructor
	 */
	public AfwezigheidInzien() {

		Abcensys.setLoadingImage(true);
	
		// Row init
		row = 0;
		
		// Header table aanmaken
		flxTableHeader = new FlexTable();
		flxTableHeader.setCellPadding(0);
		flxTableHeader.setCellSpacing(3);
		flxTableHeader.setWidth("900px");
		flxTableHeader.setStyleName("datatable");
	
		// Link widget
		HTML linkWidget = new HTML("Je bent nu hier: Abcensys &raquo; Afwezigheid inzien");
		linkWidget.setStyleName("lblLink");
		flxTableHeader.setWidget(row, 0, linkWidget);
		row++;
		
		// Image
		Image imgMijnAfwezigheid = new Image();
		imgMijnAfwezigheid.setAltText("Mijn afwezigheid");
		imgMijnAfwezigheid.setUrl("style/icon/information.png");

		// Pagina header
		HTML h1 = new HTML("<h1> " + imgMijnAfwezigheid.toString() + " Mijn afwezigheid</h1>");
		flxTableHeader.setWidget(row, 0, h1);
		
		// Row reset
		row = 0;
		
		// Data table aanmaken
		flxTable = new FlexTable();
		flxTable.setCellPadding(0);
		flxTable.setCellSpacing(3);
		flxTable.setWidth("900px");
		flxTable.setStyleName("datatable");

		// Bepalen met wat voor Gebruiker we te maken hebben.
		service.getHuidigeGebruiker(new AsyncCallback<Gebruiker>() {
			public void onSuccess(Gebruiker gebruiker) {
				// Bij een student, student gedeelte inladen
				switch (gebruiker.getType()) {
				case 0: 
					showAfwezigheidDocent(gebruiker);
					break;
				case 1:
					showAfwezigheidStudent();
					break;
				}
			}

			public void onFailure(Throwable caught) {
				// Foutmelding tonen.
				Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
				log.info("Service failure -> getHuidigeGebruiker -> " + caught.getMessage());
				Abcensys.setLoadingImage(false);
				RootPanel.get("content").add(flxTable);
			}
		});
	}

	/**
	 * Laat de AfwezigheidInzien zien voor de Docent.
	 * 
	 * @param Gebruiker
	 *            de huidige ingelogde gebruiker
	 */
	public void showAfwezigheidDocent(Gebruiker gebruiker) {
		
		// Afwezigheid voor Docent ophalen
		service.getAfwezigheidVoorDocent(new AsyncCallback<TreeMap<String, ArrayList<Afwezigheid>>>() {

			public void onFailure(Throwable caught) {
				Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
				log.info("Service failure -> getAfwezigheidVoorDocent -> " + caught.getMessage());
			}

			public void onSuccess(TreeMap<String, ArrayList<Afwezigheid>> afwezigheidregistraties) {

				if (afwezigheidregistraties != null && !afwezigheidregistraties.isEmpty()) {

					// Tabpanel
					TabPanel panel = new TabPanel();
					panel.isAnimationEnabled();
					FlowPanel flowpanel;

					// Iterator setten
					Set<Entry<String, ArrayList<Afwezigheid>>> set = afwezigheidregistraties.entrySet();
					Iterator<Entry<String, ArrayList<Afwezigheid>>> i = set.iterator();
					while (i.hasNext()) {
						// Entry setten
						Entry<String, ArrayList<Afwezigheid>> me = i.next();

						// vakCode setten
						String vakCode = me.getKey();
						
						// Afwezigheid registraties voor de vakcode setten
						ArrayList<Afwezigheid> afwezigheden = me.getValue();

						// Flowpanel
						flowpanel = new FlowPanel();
						final FlexTable ft = new FlexTable();

						if (afwezigheden != null && !afwezigheden.isEmpty()) {

							// Student
							Label lblStudent = new Label("Student");
							lblStudent.setStyleName("tableheader");

							// Afwezigheid categorie
							Label lblAfwezigheidCategorie = new Label("Afwezigheid categorie");
							lblAfwezigheidCategorie.setStyleName("tableheader");

							// Toelichting
							Label lblToelichting = new Label("Toelichting");
							lblToelichting.setStyleName("tableheader");

							// Plaatsen op het panel
							ft.setWidget(row, 0, lblStudent);
							ft.setWidget(row, 1, lblAfwezigheidCategorie);
							ft.setWidget(row, 2, lblToelichting);
							
							row++;

							for (final Afwezigheid afwezigheid : afwezigheden) {

								service.getGebruikerByEmail(afwezigheid.getEmail(), new AsyncCallback<Gebruiker>() {
									public void onFailure(Throwable caught) {
										log.info("Service failure -> getGebruikerByEmail -> " + caught.getMessage());
									}

									public void onSuccess(Gebruiker gebruiker) {
										// Toevoegen aan het FlexTable
										ft.setWidget(row, 0, new Label(gebruiker.getVoornaam() + " " + gebruiker.getAchternaam() + " [" + gebruiker.getStudentNummer() + "]"));
										ft.setWidget(row, 1, new Label(afwezigheid.getVerzuimCategorie()));
										ft.setWidget(row, 2, new Label(afwezigheid.getToelichting()));
										row++;
									}
								});
							}
						} else {
							ft.setWidget(row, 0, new Label("Er zijn geen afwezigheidregistraties bekend."));
						}

						// Plaatsen op de Tabpanel
						flowpanel.add(ft);
						panel.add(flowpanel, vakCode);
						panel.selectTab(0);

					}
					
					// Op het panel plaatsen
					flxTable.setWidget(row, 0, panel);
				} else {
					flxTable.setWidget(row, 0, new Label("Er zijn geen afwezigheidsregistraties bekend."));
				}

				// Header table
				RootPanel.get("content").add(flxTableHeader);
						
				// Data table
				RootPanel.get("content").add(flxTable);
						
				Abcensys.setLoadingImage(false);
			}
		});
	}

	/**
	 * Laat de afwezigheidsregistraties aan de student zien
	 */
	public void showAfwezigheidStudent() {

		// Afwezigheid voor de Student
		service.getAfwezigheidVoorStudent(new AsyncCallback<ArrayList<Afwezigheid>>() {

			public void onFailure(Throwable caught) {
				Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
				log.info("Service failure -> getAfwezigheidVoorStudent -> " + caught.getMessage());
			}

			public void onSuccess(ArrayList<Afwezigheid> afwezigheden) {

				// Les datum
				Label lblDatum = new Label("Datum");
				lblDatum.setStyleName("tableheader");
				
				// Les tijd
				Label lblLesTijd = new Label("Les tijd");
				lblLesTijd.setStyleName("tableheader");

				// Categorie
				Label lblCategorie = new Label("Categorie");
				lblCategorie.setStyleName("tableheader");

				// Toelichting
				Label lblToelichting = new Label("Toelichting");
				lblToelichting.setStyleName("tableheader");

				// Vakcode
				Label lblVakcode = new Label("Vakcode");
				lblVakcode.setStyleName("tableheader");

				// Opties
				Label lblBlank = new Label("Optie");
				lblBlank.setStyleName("tableheader");

				// Op panel plaatsen
				flxTable.setWidget(row, 0, lblDatum);
				flxTable.setWidget(row, 1, lblLesTijd);
				flxTable.setWidget(row, 2, lblCategorie);
				flxTable.setWidget(row, 3, lblToelichting);
				flxTable.setWidget(row, 4, lblVakcode);
				flxTable.setWidget(row, 5, lblBlank);

				row++;

				if (afwezigheden != null && !afwezigheden.isEmpty()) {

					for (final Afwezigheid afwezigheid : afwezigheden) {

						// Les bijbehorende aan de Afwezigheid ophalen
						service.getLesById(afwezigheid.getLesId(), new AsyncCallback<Les>() {
							public void onFailure(Throwable caught) {
								Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
								log.info("Service failure -> getLesById(" + afwezigheid.getLesId() + ") -> " + caught.getMessage());
							}

							public void onSuccess(Les les) {
								// Datum
								String datum = les.getLesDatum();
								// Tijd
								String tijd = les.getStartTijd() + "-" + les.getEindTijd();
								// Vak
								String vak = les.getVakCode();

								// Op het panel plaatsen
								flxTable.setWidget(row, 0, new Label(datum));
								flxTable.setWidget(row, 1, new Label(tijd));
								flxTable.setWidget(row, 2, new Label(afwezigheid.getVerzuimCategorie()));
								flxTable.setWidget(row, 3, new Label(afwezigheid.getToelichting()));
								flxTable.setWidget(row, 4, new Label(vak));

								// Verwijder Button Image
								Image imgVerwijderen = new Image();
								imgVerwijderen.setAltText("Verwijder afmelding");
								imgVerwijderen.setUrl("style/icon/delete.png");

								// Button
								Button btnVerwijderen = new Button("Verwijder afmelding");
								btnVerwijderen.setHTML("Verwijder afmelding " + imgVerwijderen.toString());
								btnVerwijderen.addClickHandler(new ClickHandler() {
									public void onClick(ClickEvent event) {
										service.verwijderAfwezigheidByIdTrancient(afwezigheid.getId(), new AsyncCallback<Boolean>() {
											public void onFailure(Throwable caught) {
												Window.alert("Het verwijderen is niet gelukt, probeer het later opnieuw.");
												log.info("Service failure -> verwijderAfwezigheidByIdTrancient(" + afwezigheid.getLesId() + ") -> " + caught.getMessage());
												new AfwezigheidInzien();
											}

											public void onSuccess(Boolean result) {
												if (result) {
													Window.alert("De afwezigheids registratie is verwijderd.");
													new AfwezigheidInzien();
												}
											}
										});
									}
								});
								// Wanneer verlopen, uitzetten
								if (!les.getLesDatum().equals(getDatumVandaag())) {
									btnVerwijderen.setEnabled(false);
								}
								// Plaatsen op panel
								flxTable.setWidget(row, 5, btnVerwijderen);
								row++;
							}
						});
					}
				} else {
					flxTable.setWidget(row, 0, new Label("Er zijn geen afwezigheidsregistraties bekend."));
				}

				// Header table
				RootPanel.get("content").add(flxTableHeader);
						
				// Data table
				RootPanel.get("content").add(flxTable);
						
				Abcensys.setLoadingImage(false);
			}
		});
	}

	/**
	 * Haalt de datum van vandaag op in dd-MM-yyyy formaat.
	 * 
	 * @return String met datum
	 */
	@SuppressWarnings("deprecation")
	public String getDatumVandaag() {
		/*
		 * MA: 2 DI: 3 WO: 4 DO: 5 VR: 6 ZA: 7 ZO: 1
		 * 
		 * Op vrijdag ziekmelden voor morgen/vandaag kan niet. De datum
		 * verschuift dan ook naar maandag Eerst dag v/d week bepalen
		 */
		Date d = new Date();

		int dag = d.getDay();

		// Vr - Ma = 3 dagen
		if (dag == 6) {
			// cal1.add(Calendar.DAY_OF_YEAR, 3);
			d.setTime(d.getTime() + (1000 * 60 * 60 * 24 * 3));
		}
		// Za - Ma = 2 dagen
		else if (dag == 7) {
			// cal1.add(Calendar.DAY_OF_YEAR, 2);
			d.setTime(d.getTime() + (1000 * 60 * 60 * 24 * 2));
		}
		// Zo - Ma = 1 dag
		else if (dag == 1) {
			// cal1.add(Calendar.DAY_OF_YEAR, 1);
			d.setTime(d.getTime() + (1000 * 60 * 60 * 24));
		}

		StringBuilder sb = new StringBuilder();
		sb.append(d.getDate());
		sb.append("-");
		sb.append(d.getMonth());
		sb.append("-");
		sb.append(d.getYear());

		// log.info("Datumvandaag: " + string.toString());
		return sb.toString();
	}
}
